import xss from 'xss'

let options = {
  whiteList: Object.assign(xss.getDefaultWhiteList(), {
    p: ['class', 'style'],
    span: ['class', 'style'],
    div: ['class', 'style'],
    img: ['src', 'style'],
    h1: ['class', 'style'],
    h2: ['class', 'style'],
    h3: ['class', 'style'],
    h4: ['class', 'style'],
    h5: ['class', 'style'],
    h6: ['class', 'style'],
    em: ['class', 'style'],
    strong: ['class', 'style'],
    s: ['class', 'style'],
    ul: ['style', 'class'],
    li: ['style', 'class'],
    ol: ['style', 'class'],
    u: ['style', 'class'],
    th: ['style', 'width', 'colspan'],
    tbody: ['class', 'style'],
    tr: ['style', 'class', 'align', 'valign', 'bgcolor', 'char', 'charoff'],
    td: [
      'style',
      'class',
      'width',
      'align',
      'valign',
      'height',
      'rowspan',
      'colspan',
      'bgcolor',
      'char',
      'charoff'
    ],
    table: [
      'width',
      'height',
      'align',
      'class',
      'style',
      'valign',
      'cellpadding',
      'cellspacing',
      'border',
      'bgcolor'
    ],
    hr: ['style'],
    b: ['style'],
    i: ['style'],
    br: [],
    pre: ['style'],
    code: ['style'],
    dl: ['style'],
    dt: ['style'],
    cite: ['style'],
    section: ['style'],
    header: ['style'],
    footer: ['style'],
    blockquote: ['style'],
    audio: ['autoplay', 'controls', 'loop', 'preload', 'src'],
    video: ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width']
  }),
  css: Object.assign(xss.getDefaultWhiteList(), {
    // 因为上面白名单中允许了标签的style属性，所以需要防止攻击者使用此途径进行攻击
    color: true,
    'background-color': true,
    width: true,
    height: true,
    'max-width': true,
    'max-height': true,
    'min-width': true,
    'min-height': true,
    'font-size': true
  })
}
let myXss = new xss.FilterXSS(options)

const englishMonthList = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']

const ARR_ENTITIES = { lt: '<', gt: '>', nbsp: ' ', amp: '&', quot: '"' }

const KEY_STR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='

const getNewDate = (date) => {
  let year = date.getFullYear()
  let month = date.getMonth()
  let day = date.getDate()
  return { year, month, day }
}

const getDate = (year, month, day) => {
  return new Date(year, month, day)
}

const englishMonth = (month) => {
  let engMonth

  englishMonthList.map(() => {
    engMonth = englishMonthList[month]
  })

  return engMonth
}

const formatDate = (date) => {
  date = Number(date)
  return date < 10 ? `0${date}` : date
}
// 判断是否是闰年
const isLeapYear = (year) => {
  return year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)
}
// 2.获得每个月的日期有多少，注意 month - [0-11]
const getMonthCount = (year, month) => {
  let arr = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  let count = arr[month] || (isLeapYear(year) ? 29 : 28)
  return Array.from(new Array(count), (item, value) => value + 1)
}

//节流，设置默认时间200毫秒
const throttle = (func, gapTime = 200) => {
  if (typeof func !== 'function') {
    throw new TypeError('need a function')
  }
  gapTime = +gapTime || 0
  let lastTime = 0

  return function() {
    const self = this
    const args = arguments
    let time = +new Date()
    if (time - lastTime > gapTime || !lastTime) {
      func.apply(self, args)
      lastTime = time
    }
  }
}

//防抖，设置默认时间200毫秒
const debounce = (func, wait = 200) => {
  if (typeof func !== 'function') {
    throw new TypeError('need a function')
  }
  wait = +wait || 0

  let timeId = null

  return function() {
    const self = this
    const args = arguments

    if (timeId) {
      clearTimeout(timeId) // 清除定时器，重新设定一个新的定时器
    }
    timeId = setTimeout(() => {
      func.apply(self, args) // arguments 是传给函数的参数，这里是 event  对象
    }, wait)
  }
}

const responesAssemble = (res) => {
  let { code, message } = res
  let data = res.data || {}
  if (data.dataList === undefined) {
    data.items = data.items || [] // items可能为空，设置为空数组，避免页面出现空指针
    data.dataList = data.items
  }
  data.totalCount = data.total
  return {
    code,
    message,
    attribute: data
  }
}

const requestAssemble = (obj) => {
  let ret = {}
  Object.keys(obj).forEach((key) => {
    switch (key) {
      case 'rows':
        ret.pageSize = obj[key]
        break
      case 'page':
        ret.pageIndex = obj[key]
        break
      case 'contestId':
        ret.sceneId = obj[key]
        break
      default:
        ret[key] = obj[key]
    }
  })
  return ret
}

const parseJson = (jsonStr) => {
  let ret
  try {
    ret = JSON.parse(jsonStr)
  } catch (error) {
    ret = {}
  }
  return ret
}

const escape2Html = (str) => {
  if (str) {
    return str
      .replace(/&(lt|gt|amp|quot|nbsp);/gi, function(all, t) {
        return ARR_ENTITIES[t]
      })
      .replace(/＜/g, '<')
      .replace(/＞/g, '>')
      .replace(/＆/g, '&')
      .replace(/＂/g, '"')
  } else {
    return ''
  }
}

const html2Escape = (str) => {
  if (str) {
    return str
      .replace(/\&nbsp;/g, ' ')
      .replace(/\&lt;/g, '<')
      .replace(/\&gt;/g, '>')
      .replace(/\&amp;/g, '&')
      .replace(/\&quot;/g, '"')
      .replace(/\&/g, '＆')
      .replace(/\</g, '＜')
      .replace(/\>/g, '＞')
  } else {
    return ''
  }
}

// 用于给iview的message组件使用，将<、>、&符号转义一下
const getMessageText = (str) => {
  if (str) {
    return str
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
  } else {
    return ''
  }
}

const encode = (input) => {
  var output = ''
  var chr1, chr2, chr3, enc1, enc2, enc3, enc4
  var i = 0
  input = _utf8_encode(input)

  while (i < input.length) {
    chr1 = input.charCodeAt(i++)
    chr2 = input.charCodeAt(i++)
    chr3 = input.charCodeAt(i++)

    enc1 = chr1 >> 2
    enc2 = ((chr1 & 3) << 4) | (chr2 >> 4)
    enc3 = ((chr2 & 15) << 2) | (chr3 >> 6)
    enc4 = chr3 & 63

    if (isNaN(chr2)) {
      enc3 = enc4 = 64
    } else if (isNaN(chr3)) {
      enc4 = 64
    }

    output =
      output +
      KEY_STR.charAt(enc1) +
      KEY_STR.charAt(enc2) +
      KEY_STR.charAt(enc3) +
      KEY_STR.charAt(enc4)
  }

  return output
}

const decode = (e) => {
  var t = ''
  var n, r, i
  var s, o, u, a
  var f = 0
  e = e.replace(/[^A-Za-z0-9+/=]/g, '')
  while (f < e.length) {
    s = KEY_STR.indexOf(e.charAt(f++))
    o = KEY_STR.indexOf(e.charAt(f++))
    u = KEY_STR.indexOf(e.charAt(f++))
    a = KEY_STR.indexOf(e.charAt(f++))
    n = (s << 2) | (o >> 4)
    r = ((o & 15) << 4) | (u >> 2)
    i = ((u & 3) << 6) | a
    t = t + String.fromCharCode(n)
    if (u != 64) {
      t = t + String.fromCharCode(r)
    }
    if (a != 64) {
      t = t + String.fromCharCode(i)
    }
  }
  t = _utf8_decode(t)
  return t
}

const _utf8_encode = (string) => {
  if (!string) {
    return ''
  }
  string = string.replace(/\r\n/g, '\n')
  var utftext = ''

  for (var n = 0; n < string.length; n++) {
    var c = string.charCodeAt(n)

    if (c < 128) {
      utftext += String.fromCharCode(c)
    } else if (c > 127 && c < 2048) {
      utftext += String.fromCharCode((c >> 6) | 192)
      utftext += String.fromCharCode((c & 63) | 128)
    } else {
      utftext += String.fromCharCode((c >> 12) | 224)
      utftext += String.fromCharCode(((c >> 6) & 63) | 128)
      utftext += String.fromCharCode((c & 63) | 128)
    }
  }

  return utftext
}

// 时间戳转字符串，单位秒
const timestampToString = (timestamp) => {
  if (typeof timestamp !== 'number') {
    return 'isNaN'
  }
  timestamp = Math.floor(timestamp)
  let second = timestamp % 60
  let minute = Math.floor(timestamp / 60) % 60
  let hour = Math.floor(timestamp / 3600)
  return `${hour === 0 ? '' : hour < 10 ? `0${hour}:` : `${hour}:`}${
    minute < 10 ? `0${minute}` : minute === 60 ? '00' : minute
  }:${second < 10 ? `0${second}` : second}`
}

const _utf8_decode = (e) => {
  var t = '',
    r,
    c1,
    c2,
    c3
  var n = 0
  r = c1 = c2 = 0
  while (n < e.length) {
    r = e.charCodeAt(n)
    if (r < 128) {
      t += String.fromCharCode(r)
      n++
    } else if (r > 191 && r < 224) {
      c2 = e.charCodeAt(n + 1)
      t += String.fromCharCode(((r & 31) << 6) | (c2 & 63))
      n += 2
    } else {
      c2 = e.charCodeAt(n + 1)
      c3 = e.charCodeAt(n + 2)
      t += String.fromCharCode(((r & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))
      n += 3
    }
  }
  return t
}

const paserTaskStatus = (val) => {
  switch (val) {
    case 'running':
      return '运行中'
    case 'error':
    case 'failed':
      return '失败'
    case 'completed':
      return '完成'
    case 'initialized':
      return '初始化'
    case 'starting':
      return '启动中'
    case 'closing':
      return '关闭中'
    default:
      return ''
  }
}
// 秒转时间 分隔符 ：
const getSeconds = (seconds) => {
  let secondTime = parseInt(seconds) // 秒
  let minuteTime = 0 // 分
  let hourTime = 0 // 时
  if (secondTime > 60) {
    //如果秒数大于60，将秒数转换成整数
    //获取分钟，除以60取整数，得到整数分钟
    minuteTime = parseInt(secondTime / 60)
    //获取秒数，秒数取佘，得到整数秒数
    secondTime = parseInt(secondTime % 60)
    //如果分钟大于60，将分钟转换成小时
    if (minuteTime > 60) {
      //获取小时，获取分钟除以60，得到整数小时
      hourTime = parseInt(minuteTime / 60)
      //获取小时后取佘的分，获取分钟除以60取佘的分
      minuteTime = parseInt(minuteTime % 60)
    }
  }
  let result = ''
  if (secondTime >= 0 && secondTime < 10) {
    result = '0' + parseInt(secondTime) + ''
  } else {
    result = '' + parseInt(secondTime) + ''
  }
  if (minuteTime >= 0 && minuteTime < 10) {
    result = '0' + parseInt(minuteTime) + ':' + result
  } else {
    result = '' + parseInt(minuteTime) + ':' + result
  }
  if (hourTime >= 0 && hourTime < 10) {
    result = '0' + parseInt(hourTime) + ':' + result
  } else {
    result = '' + parseInt(hourTime) + ':' + result
  }
  return result
}
//秒数转时间 分隔符 时、分、秒
const formatSeconds = (seconds) => {
  let secondTime = parseInt(seconds) // 秒
  let minuteTime = 0 // 分
  let hourTime = 0 // 小时
  if (secondTime > 60) {
    //如果秒数大于60，将秒数转换成整数
    //获取分钟，除以60取整数，得到整数分钟
    minuteTime = parseInt(secondTime / 60)
    //获取秒数，秒数取余，得到整数秒数
    secondTime = parseInt(secondTime % 60)
    //如果分钟大于60，将分钟转换成小时
    if (minuteTime > 60) {
      //获取小时，获取分钟除以60，得到整数小时
      hourTime = parseInt(minuteTime / 60)
      //获取小时后取余的分，获取分钟除以60取余的分
      minuteTime = parseInt(minuteTime % 60)
    }
  }
  let result = ''
  if (secondTime >= 0 && secondTime < 10) {
    result = '0' + parseInt(secondTime) + '秒'
  } else {
    result = '' + parseInt(secondTime) + '秒'
  }
  if (minuteTime >= 0 && minuteTime < 10) {
    result = '0' + parseInt(minuteTime) + '分' + result
  } else {
    result = '' + parseInt(minuteTime) + '分' + result
  }
  if (hourTime >= 0 && hourTime < 10) {
    result = '0' + parseInt(hourTime) + '小时' + result
  } else {
    result = '' + parseInt(hourTime) + '小时' + result
  }
  return result
}

// 秒数转换为 天、时、分、秒
const dayTime = (seconds) => {
  let second = parseInt(seconds) % 60 // 直接取模数
  let min = parseInt(seconds / 60) % 60
  let hour = parseInt(seconds / 60 / 60) % 24
  let day = parseInt(seconds / 60 / 60 / 24)
  let result = second + '秒' // 如果是 0 秒 ，直接赋值

  if (seconds) {
    second = second >= 0 && second < 10 ? '0' + second : second
    result = second + '秒'
  }
  if (seconds) {
    min = min >= 0 && min < 10 ? '0' + min : min
    result = min + '分' + second + '秒'
  }
  if (hour) {
    hour = hour >= 0 && hour < 10 ? '0' + hour : hour
    result = hour + '小时' + min + '分' + second + '秒'
  }
  if (day) {
    day = day >= 0 && day < 10 ? '0' + day : day
    result = day + '天' + hour + '小时' + min + '分' + second + '秒'
  }
  return result
}

// 毫秒转时间 分隔符 ：
const getMilliSecond = (seconds) => {
  let secondTime = parseInt(seconds / 1000) // 秒
  let minuteTime = 0 // 分
  let hourTime = 0 // 时
  if (secondTime > 60) {
    //如果秒数大于60，将秒数转换成整数
    //获取分钟，除以60取整数，得到整数分钟
    minuteTime = parseInt(secondTime / 60)
    //获取秒数，秒数取佘，得到整数秒数
    secondTime = parseInt(secondTime % 60)
    //如果分钟大于60，将分钟转换成小时
    if (minuteTime > 60) {
      //获取小时，获取分钟除以60，得到整数小时
      hourTime = parseInt(minuteTime / 60)
      //获取小时后取佘的分，获取分钟除以60取佘的分
      minuteTime = parseInt(minuteTime % 60)
    }
  }
  let result = ''
  if (secondTime >= 0 && secondTime < 10) {
    result = '0' + parseInt(secondTime) + ''
  } else {
    result = '' + parseInt(secondTime) + ''
  }
  if (minuteTime >= 0 && minuteTime < 10) {
    result = '0' + parseInt(minuteTime) + ':' + result
  } else {
    result = '' + parseInt(minuteTime) + ':' + result
  }
  if (hourTime >= 0 && hourTime < 10) {
    result = '0' + parseInt(hourTime) + ':' + result
  } else {
    result = '' + parseInt(hourTime) + ':' + result
  }
  return result
}

const format = (date, fmt = 'yyyy-MM-dd hh:mm:ss') => {
  var o = {
    'M+': date.getMonth() + 1, //月份
    'd+': date.getDate(), //日
    'h+': date.getHours(), //小时
    'm+': date.getMinutes(), //分
    's+': date.getSeconds(), //秒
    'q+': Math.floor((date.getMonth() + 3) / 3), //季度
    S: date.getMilliseconds() //毫秒
  }
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
  }
  for (var k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) {
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
      )
    }
  }
  return fmt
}
//获取数据类型
const getType = (data) => {
  let type = typeof data
  switch (type) {
    case 'string':
      try {
        JSON.parse(data)
        return 'json'
      } catch (e) {
        return type
      }
    case 'object':
      if (data === null) return 'null'
      return Array.isArray(data) ? 'array' : data instanceof Date ? 'date' : type
    default:
      return type
  }
}
/**
 * 格式化时间
 */
const TimeFormatter = {
  // 年月日
  ydm(timestamp, separator = '-') {
    let res, time
    if (getType(timestamp) === 'number' && timestamp > 0) {
      time = new Date(timestamp)
      res = [time.getFullYear(), formatDate(time.getMonth() + 1), formatDate(time.getDate())].join(
        separator
      )
      return res
    }
    console.error('[TimeFormatter]: error timestamp')
  },
  // 时分秒
  hms(timestamp) {
    let res, time
    if (getType(timestamp) === 'number' && timestamp > 0) {
      time = new Date(timestamp)
      res = [
        formatDate(time.getHours()),
        formatDate(time.getMinutes()),
        formatDate(time.getSeconds())
      ].join(':')
      return res
    }
    console.error('[TimeFormatter]: error timestamp')
  },
  // 年月日-时分秒
  time(timestamp, separator = '-') {
    if (getType(timestamp) === 'number' && timestamp > 0)
      return this.ydm(timestamp, separator) + ' ' + this.hms(timestamp)
    console.error('[TimeFormatter]: error timestamp')
  }
}
//连线转为小驼峰
const getCamelCase = (str) => {
  const reg = /-\w/g
  let delStr = str.replace(reg, function($) {
    return $.slice(1).toUpperCase()
  })
  return delStr
}
//小驼峰转为连线
const getKebabCase = (str) => {
  const reg = /[A-Z]/g
  let delStr = str.replace(reg, function($) {
    return '-' + $.toLowerCase()
  })
  return delStr
}
const escapeRequestArgument = (request) => {
  if (request.params) {
    let params = JSON.parse(JSON.stringify(request.params))
    if (JSON.stringify(params) !== '{}') {
      request.params = recursiveEscape(params, true)
    }
  }
  if (request.data) {
    let data = JSON.parse(JSON.stringify(request.data))
    if (JSON.stringify(data) !== '{}' && !(data instanceof Blob)) {
      // blob类型的数据不需要转义
      request.data = recursiveEscape(data, true)
    }
  }
}

const escapeResponseArgument = (response) => {
  if (response.params) {
    recursiveEscape(response.params, false)
    if (JSON.stringify(response.params) === '{}') {
      delete response.params
    }
  }
  if (response.data) {
    recursiveEscape(response.data, false)
    if (JSON.stringify(response.data) === '{}' && !(response.data instanceof Blob)) {
      // blob类型的数据不需要转义
      delete response.data
    }
  }
}

/**
 * 递归转义数据
 * @param {*} data 需要处理的数据
 * @param {*} type 转义类型 true: 处理请求，使用html2Escape方法， false:处理相应，使用escape2Html方法
 */
const recursiveEscape = (data, type) => {
  let isJson = false
  let fnName = type ? html2Escape : escape2Html
  if (typeof data === 'string') {
    try {
      isJson = true
      data = JSON.parse(data)
    } catch (error) {}
  }
  if (typeof data === 'object') {
    if (Array.isArray(data)) {
      // 操作的是数组
      data.forEach((item) => {
        if (typeof item === 'string') {
          if (notTimeStr(item)) {
            item = decompilation(item) // 把转义过的数据，反转义成正常数据
            item = type ? fnName(myXss.process(item)) : fnName(myXss.process(fnName(item))) // 请求时，转义前处理xss，响应时，转移后处理xss
          }
        } else if (typeof item === 'object') {
          recursiveEscape(item, type)
        }
      })
    } else {
      // 操作对象
      try {
        Object.keys(data).forEach((key) => {
          let item = data[key]
          if (typeof item === 'string') {
            if (notTimeStr(item)) {
              item = decompilation(item) // 把转义过的数据，反转义成正常数据
              let str = type ? fnName(myXss.process(item)) : fnName(myXss.process(fnName(item))) // 请求时，转义前处理xss，响应时，转移后处理xss
              data[key] = str
            }
          } else if (typeof item === 'object') {
            recursiveEscape(item, type)
          }
        })
      } catch (error) {
        // 转义失败的数据，不做处理
      }
    }
  }
  return isJson ? JSON.stringify(data) : data
}

// 存在转义后的字符，就还原一次
const decompilation = (str) => {
  if (
    str.indexOf('&amp;') !== -1 ||
    str.indexOf('&lt;') !== -1 ||
    str.indexOf('&gt;') !== -1 ||
    str.indexOf('&nbsp;') !== -1 ||
    str.indexOf('＜') !== -1 ||
    str.indexOf('＞') !== -1 ||
    str.indexOf('＆') !== -1
  ) {
    return decompilation(escape2Html(str))
  } else {
    return str
  }
}

const notTimeStr = (str) => {
  return !/^\d{4}-\d{1,2}-\d{1,2}( \d{2}(:\d{2}){0,2})?/.test(str)
}

// 只适用于富文本回显展示的转义，因为使用的插件会忽略掉script标签，所以将它特殊处理
const escapeScript = (str) => {
  if (str) {
    return str
      .replace(/<script>/g, '<span><</span>script>')
      .replace(/<script /g, '<span><</span>script ')
      .replace(/<\/script>/g, '<span><</span>/script>')
  }
  return ''
}

const sceneStatusEscape = (status) => {
  switch (status) {
    case 0: // 准备中
    case 1:
      return '0' // 准备完毕
    case 2: // 开始中
    case 3: // 裁判评判阶段
    case 5:
      return '2' // 暂停
    case 4:
      return '4' // 结束
    default:
      return '0'
  }
}

// 不要显示秒 2022-03-09 34:34:34
const showTimeNotSecond = (time) => {
  if (!time) {
    return
  }
  return time.substr(0, time.length - 3)
}

const noFilter = (val) => {
  let num = val + 1
  let str
  switch (num) {
    case 1:
      str = 'A'
      break
    case 2:
      str = 'B'
      break
    case 3:
      str = 'C'
      break
    case 4:
      str = 'D'
      break
    case 5:
      str = 'E'
      break
    case 6:
      str = 'F'
      break
    case 7:
      str = 'G'
      break
    case 8:
      str = 'H'
      break
    case 9:
      str = 'I'
      break
    case 10:
      str = 'J'
      break
    case 11:
      str = 'K'
      break
    case 12:
      str = 'L'
      break
    default:
      str = ''
      break
  }
  return str
}

const parseDifficulty = (difficulty) => {
  let difficultyStr = ''
  if (difficulty) {
    difficultyStr = difficulty.toLowerCase()
  }
  switch (difficultyStr) {
    case 'simple':
      return {
        text: '简单',
        color: '#2db7f5'
      }
    case 'commonly':
      return {
        text: '一般',
        color: '#19be6b'
      }
    case 'medium':
      return {
        text: '中等',
        color: '#ff9900'
      }
    case 'hard':
      return {
        text: '较难',
        color: '#ed4014'
      }
  }
}
const filterAnswerNo = (val) => {
  let str = ''
  switch (val) {
    case 1:
      str = 'A'
      break
    case 2:
      str = 'B'
      break
    case 3:
      str = 'C'
      break
    case 4:
      str = 'D'
      break
    case 5:
      str = 'E'
      break
    case 6:
      str = 'F'
      break
    case 7:
      str = 'G'
      break
    case 8:
      str = 'H'
      break
    case 9:
      str = 'I'
      break
    case 10:
      str = 'J'
      break
    case 11:
      str = 'K'
      break
    case 12:
      str = 'L'
      break
    default:
      str = ''
      break
  }
  return str
}

//取消空的和all
const dealSearchParams = (obj) => {
  if (obj.toString() !== '[object Object]') {
    return obj
  }
  let copyObj = JSON.parse(JSON.stringify(obj))
  Object.keys(copyObj).filter((key) => {
    if (isEmpty(copyObj[key]) || copyObj[key] === 'all') {
      delete copyObj[key]
    }
  })
  return copyObj
}

// 导出服务器文件
const downloadBlob = (filename, blob) => {
  let url = window.URL.createObjectURL(blob),
    a = document.createElement('a')
  a.style.display = 'none'
  a.href = url
  a.setAttribute('download', filename)
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  window.URL.revokeObjectURL(url)
}

const getVersion = (userAgent, reg) => {
  var reBrowser = new RegExp(reg)
  reBrowser.test(userAgent)
  return parseFloat(RegExp['$1'])
}

const getUserAgentInfo = () => {
  var userAgent = navigator.userAgent
  var version, type
  if (/opera/i.test(userAgent) || /OPR/i.test(userAgent)) {
    version = getVersion(userAgent, 'OPR/(\\d+\\.+\\d+)')
    type = 'Opera'
  } else if (/compatible/i.test(userAgent) && /MSIE/i.test(userAgent)) {
    version = getVersion(userAgent, 'MSIE (\\d+\\.+\\d+)')
    type = 'IE'
  } else if (/Edge/i.test(userAgent)) {
    version = getVersion(userAgent, 'Edge/(\\d+\\.+\\d+)')
    type = 'Edge'
  } else if (/Firefox/i.test(userAgent)) {
    version = getVersion(userAgent, 'Firefox/(\\d+\\.+\\d+)')
    type = 'Firefox'
  } else if (/Safari/i.test(userAgent) && !/Chrome/i.test(userAgent)) {
    version = getVersion(userAgent, 'Safari/(\\d+\\.+\\d+)')
    type = 'Safari'
  } else if (/Chrome/i.test(userAgent) && /Safari/i.test(userAgent)) {
    version = getVersion(userAgent, 'Chrome/(\\d+\\.+\\d+)')
    type = 'Chrome'
  } else if (!!window.ActiveXObject || 'ActiveXObject' in window) {
    version = 11
    type = 'IE'
  }
  return {
    version,
    type
  }
}

const buildDictTree = (nodes) => {
  function buildTree(nodes, parentid = '', level = 0) {
    level++
    let tree = []
    for (let i = 0; i < nodes.length; i++) {
      if (!nodes[i].parentid) nodes[i].parentid = ''
      if (nodes[i].parentid === parentid) {
        nodes[i].level = level
        let children = buildTree(nodes, nodes[i].dictid, level)
        if (children.length) {
          nodes[i].children = children
        }
        tree.push({
          ...nodes[i],
          label: nodes[i].dictname,
          value: nodes[i].dictid
        })
      }
    }
    return tree
  }
  return buildTree(nodes)
}

//对题目答案进行排序
const sortQuestionAnswer = (answer) => {
  if (!answer) {
    return
  } else if (answer.length > 0 && answer[0].no) {
    answer.sort(function(a, b) {
      return parseInt(a.no) - parseInt(b.no)
    })
  }
  return answer
}
export {
  sceneStatusEscape,
  getNewDate,
  getDate,
  englishMonth,
  formatDate,
  getMonthCount,
  isLeapYear,
  throttle,
  debounce,
  responesAssemble,
  requestAssemble,
  parseJson,
  escape2Html,
  html2Escape,
  getMessageText,
  encode,
  decode,
  timestampToString,
  paserTaskStatus,
  format,
  escapeRequestArgument,
  escapeResponseArgument,
  escapeScript,
  showTimeNotSecond,
  noFilter,
  parseDifficulty,
  getSeconds,
  formatSeconds,
  dayTime,
  getMilliSecond,
  filterAnswerNo,
  dealSearchParams,
  downloadBlob,
  TimeFormatter,
  getCamelCase,
  getKebabCase,
  getUserAgentInfo,
  buildDictTree,
  sortQuestionAnswer
}
